/*************************************************
 * 
 * Copyright by Bruno Eberhard
 * 
 * Created on 25.08.2005
 *
 *************************************************/
package fightplan.print;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Line2D;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterJob;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JScrollPane;

import fightplan.algorithmen.ko.FinalrundePanel;
import fightplan.business.Category;
import fightplan.business.Sheet;
import fightplan.business.Tournament;
import fightplan.business.Winner;
import fightplan.core.Resources;
import fightplan.core.Style;

public class DrawingPrintable implements Printable {
	private final float INCH = 72;
	private final float CM = INCH * 100 / 254;
	private Tournament tournament;
	private List<Sheet> sheets;
	private boolean done = false;

	public DrawingPrintable(Tournament tournament, List<Sheet> sheets) {
		this.tournament = tournament;
		this.sheets = sheets;
		PrinterJob printJob = PrinterJob.getPrinterJob();
		PageFormat documentPageFormat = new PageFormat();
		documentPageFormat.setPaper(createA4Paper());
		documentPageFormat.setOrientation(PageFormat.LANDSCAPE);
		printJob.setPrintable(this, documentPageFormat);

		if (printJob.printDialog()) {
			try {
				printJob.print();
				done = true;
			} catch (Exception PrintException) {
				PrintException.printStackTrace();
			}
		}
	}

	public boolean isDone() {
		return done;
	}

	public int print(Graphics g, PageFormat pageFormat, int page) {
		if (sheets.size() <= page)
			return (NO_SUCH_PAGE);

		Category category = sheets.get(page).category;
		int sheetNo = sheets.get(page).sheetNo;

		Graphics2D g2d = (Graphics2D) g;
		g2d.setColor(Color.black);
		// double width = pageFormat.getImageableWidth();
		// double height = pageFormat.getImageableHeight();

		// --- Translate the origin to be (0,0)
		g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());

		drawHeader(g2d, 0.0 * CM, 0.4 * CM, category, sheetNo, sheetNo == -1);

		Component component;
		boolean finalrunde = false;
		if (sheetNo == -1) {
			component = category.getLayout().getEndSheet();
		} else if (sheetNo == -2) {
			FinalrundePanel finalrundePanel = (FinalrundePanel) category.getLayout().getFinalrundeSheet();
			component = finalrundePanel.getComponent(0);
			finalrunde = true;
		} else {
			component = category.getLayout().getSheetComponent(sheetNo);
		}

		if (component instanceof JScrollPane) {
			// ((JScrollPane)component).getViewport().setOpaque(true);
			((JScrollPane) component).getViewport().setBackground(Color.WHITE);
		} else if (component instanceof JComponent) {
			((JComponent) component).setOpaque(false);
			((JComponent) component).setBorder(null);
		}

		if (!finalrunde) {
			component.setBounds(0, 0, (int) (26.9 * CM), (int) (14.5 * CM));
			component.doLayout();
			g2d.translate(0, (int) (4.4 * CM));
		} else {
			component.setBounds(0, 0, (int) (26.9 * CM), (int) (12.5 * CM));
			component.doLayout();
			g2d.translate(0, (int) (6.4 * CM));
		}

		g2d.setStroke(new BasicStroke(0.7F));
		component.print(g2d);

		if (component instanceof JScrollPane) {
			((JScrollPane) component).getViewport().setBackground(Style.UNUSED_TABLE_SPACE);
		}

		return (PAGE_EXISTS);
	}

	private void drawHeader(Graphics2D g2d, double x, double y, Category category, int page, boolean showRanking) {
		g2d.setStroke(new BasicStroke(2));
		Rectangle r = new Rectangle();
		r.setRect(x, y, 28.5 * CM, 1.4 * CM);
		g2d.draw(r);

		g2d.setStroke(new BasicStroke(0.7F));
		Line2D.Double line = new Line2D.Double();
		line.setLine(x + 15.7 * CM, y, x + 15.7 * CM, y + 1.4 * CM);
		g2d.draw(line);
		line.setLine(x + 17.2 * CM, y, x + 17.2 * CM, y + 1.4 * CM);
		g2d.draw(line);
		line.setLine(x + 17.2 * CM, y + 0.7 * CM, x + 24.0 * CM, y + 0.7 * CM);
		g2d.draw(line);
		line.setLine(x + 21.5 * CM, y + 0.7 * CM, x + 21.5 * CM, y + 1.4 * CM);
		g2d.draw(line);

		line.setLine(x + 24.0 * CM, y, x + 24.0 * CM, y + 1.4 * CM);
		g2d.draw(line);

		// Kategorie Name
		g2d.setFont(g2d.getFont().deriveFont(20.0F));
		g2d.drawString(category.getNameOrDescription(), (float) (0.4 * CM), (float) (y + 1.0 * CM));
		String blattNr = page >= 0 ? (page + 1) + "/" + category.getLayout().getSheetCount() : "   -";
		g2d.drawString(blattNr, (float) (15.9 * CM), (float) (y + 1.0 * CM));

		// Turnier
		g2d.setFont(g2d.getFont().deriveFont(9.0F));
		g2d.drawString(tournament.getName(), (float) (17.5 * CM), (float) (y + 0.5 * CM));
		g2d.drawString(tournament.getPlace(), (float) (17.5 * CM), (float) (y + 1.2 * CM));
		g2d.drawString(tournament.getDate(), (float) (22.0 * CM), (float) (y + 1.2 * CM));

		// Wappen
		g2d.drawImage(Resources.getImage("skv_logo.png"), (int) (24.3 * CM), (int) (0.6 * CM), (int) (1.0 * CM),
				(int) (0.4 * CM), null);
		g2d.drawString("Schweizerischer", (float) (x + 25.4 * CM), (float) (y + 0.5 * CM));
		g2d.drawString("Karateverband", (float) (x + 25.4 * CM), (float) (y + 0.9 * CM));

		// Verantwortlickeiten
		String footerLeft = "";
		if (tournament.getPersonTournament() != null && tournament.getPersonTournament().length() > 0) {
			footerLeft += "Wettkampf - Verantwortlicher: " + tournament.getPersonTournament() + "            ";
		}
		if (tournament.getPersonDrawing() != null && tournament.getPersonDrawing().length() > 0) {
			footerLeft += "Verantwortlich für die Losung: " + tournament.getPersonDrawing();
		}
		g2d.drawString(footerLeft, (float) (x + 0.4 * CM), (float) (y + 19.3 * CM));

		String footerRight = "";
		if (category.getPlanTime().length() > 0) {
			// footerRight += "Zeit Auslosung: " + category.getPlanTime();
			footerRight += category.getPlanTime();
		}
		Double width = g2d.getFontMetrics().getStringBounds(footerRight, g2d).getWidth();
		g2d.drawString(footerRight, (float) (x + 28.5 * CM - width), (float) (y + 19.3 * CM));

		g2d.setStroke(new BasicStroke(2));
		r.setRect(x, y + 3.4 * CM, 4 * CM, 0.8 * CM);
		g2d.draw(r);
		g2d.setFont(g2d.getFont().deriveFont(12.0F));
		if (page == -1) {
			g2d.drawString("Final", (float) (x + 0.2 * CM), (float) (y + 4.0 * CM));
		} else if (page == -2) {
			g2d.drawString("Finalrunde", (float) (x + 0.2 * CM), (float) (y + 4.0 * CM));
		} else if (page >= 0) {
			g2d.drawString("Tableau " + (page + 1), (float) (x + 0.2 * CM), (float) (y + 4.0 * CM));
		}

		if (showRanking) {
			List<Winner> winners = category.getPlan().getWinners();
			int winnerCount = Math.min(winners.size(), 4);

			g2d.setStroke(new BasicStroke(2));
			r.setRect(x + 21.5 * CM, y + 3.8 * CM, 7 * CM, (0.7 * winnerCount) * CM);
			g2d.draw(r);
			g2d.setFont(g2d.getFont().deriveFont(12.0F));
			g2d.drawString("Rangliste", (float) (x + (21.7 + 0.2) * CM), (float) (y + (0.4 + 3) * CM));

			g2d.setStroke(new BasicStroke(0.7F));
			for (int i = 0; i < winnerCount - 1; i++) {
				line.setLine(x + 21.5 * CM, y + (4.4 + 0.7 * i) * CM, x + 28.5 * CM, y + (4.4 + 0.7 * i) * CM);
				g2d.draw(line);
			}
			for (int i = 0; i < winnerCount; i++) {
				drawHeaderField(g2d, x + 21.5 * CM, y + (3.8 + 0.7 * i) * CM, 7 * CM, winners.get(i)
						.formatPrintString());

			}
		}

	}

	private void drawHeaderField(Graphics2D g2d, double x, double y, double width, String text) {
		g2d.setFont(g2d.getFont().deriveFont(8.0F));
		g2d.drawString(text, (float) (x + 0.2 * CM), (float) (y + 0.4 * CM));
	}

	private Paper createA4Paper() {
		Paper a4Paper = new java.awt.print.Paper();

		double paperWidth = 8.26;
		double paperHeight = 11.69;
		a4Paper.setSize(paperWidth * 72.0, paperHeight * 72.0);

		double leftMargin = 0.2;
		double rightMargin = 0.2;
		double topMargin = 0.2;
		double bottomMargin = 0.2;

		a4Paper.setImageableArea(leftMargin * 72.0, topMargin * 72.0, (paperWidth - leftMargin - rightMargin) * 72.0,
				(paperHeight - topMargin - bottomMargin) * 72.0);
		return a4Paper;
	}

}
